// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/PlayerController.h"
#include "AuraPlayerController.generated.h"

class UDamageTextComponent;
class USplineComponent;
class UAuraAbilitySystemComponent;
struct FGameplayTag;
class UInputConfig;
class IEnemyInterface;
struct FInputActionValue;
class UInputAction;
class UInputMappingContext;
/**
 * 玩家控制类,管理玩家操作
 * 
 */
UCLASS()
class AURA_API AAuraPlayerController : public APlayerController
{
	GENERATED_BODY()

	UPROPERTY()
	TObjectPtr<UAuraAbilitySystemComponent> AuraAbilitySystemComponent;

	UPROPERTY(EditDefaultsOnly)
	TSubclassOf<UDamageTextComponent> DamageTextComponentClass;

public:

	AAuraPlayerController();

	/** 玩家帧更新,仅在 PlayerController有 PlayInput对象生效 */
	virtual void PlayerTick(float DeltaTime) override;

	UAuraAbilitySystemComponent* GetASC();

	/** 显示伤害数值 */
	UFUNCTION(Client, Reliable)
	void ShowDamageNumber(float DamageAmount, ACharacter* TargetCharacter, bool bIsBlockedHit, bool bIsCriticalHit);

protected:

	virtual void BeginPlay() override;

private:

	// ----------------------------------------------------------------------------------------------------------------
	//	输入相关
	// ----------------------------------------------------------------------------------------------------------------

	/** 自定义输入绑定 */
	virtual void SetupInputComponent() override;

	UPROPERTY(EditAnywhere, Category = "Input")
	TObjectPtr<UInputMappingContext> AuraContext;

	UPROPERTY(EditAnywhere, Category = "Input")
	TObjectPtr<UInputAction> MoveAction;


	UPROPERTY(EditAnywhere, Category= "Input")
	TObjectPtr<UInputAction> ShiftAction;

	bool bShiftKeyDown = false;
	void OnShiftKeyStart();
	void OnShiftKeyReleased();

	/** 能力对应按键绑定 */
	UPROPERTY(EditDefaultsOnly, Category = "Input")
	TObjectPtr<UInputConfig> InputConfig;


	/** MoveAction trigger时逻辑 */
	void Move(const FInputActionValue& ValueInputAction);

	/** 当标记的输入start时触发 */
	void OnTaggedInputStarted(FGameplayTag InputTag);

	/** 当标记的输入trigger时触发 */
	void OnTaggedInputTriggered(FGameplayTag InputTag);

	/** 当标记的输入completed时触发 */
	void OnTaggedInputReleased(FGameplayTag InputTag);


	// ----------------------------------------------------------------------------------------------------------------
	//	自动寻路相关  TODO:优化自动寻路
	// ----------------------------------------------------------------------------------------------------------------

	/** 自动寻路时生成的样条线 */
	UPROPERTY(EditDefaultsOnly)
	TObjectPtr<USplineComponent> SplineComponent;

	/** 短按阈值,超过阈值将向目标方向移动 */
	UPROPERTY(EditDefaultsOnly)
	float ShortPressThreshold = 3.f;

	/** 鼠标点击的位置 */
	FVector ClickPosition = FVector::ZeroVector;

	/** 鼠标按住了多久 */
	float HoldTime = 0.f;

	/** 当前是否自动移动 */
	bool bAutomaticMovement = false;

	/** 当前鼠标是否选中敌人 */
	bool bSelected = false;

	/** 当角色和目标距离在此半径外时才自动移动 */
	UPROPERTY(EditDefaultsOnly)
	float AutomaticMovementRadius = 50.f;

	/** 进行自动寻路 */
	void AutomaticPathfinding();

	// ----------------------------------------------------------------------------------------------------------------
	//	光标相关 TODO:理解
	// ----------------------------------------------------------------------------------------------------------------

	/** 光标上一个击中的Actor */
	IEnemyInterface* LastActor;

	/** 光标当前击中的Actor */
	IEnemyInterface* ThisActor;

	/** 光标拾取结果 */
	FHitResult CursorHitResult;

	/** 光标击中相关逻辑 */
	void CursorHit();
};
